﻿using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

namespace SolutionSettings {
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [ProvideAutoLoad(UIContextGuids.NoSolution)]
    [InstalledProductRegistration("#110", "#112", /*version*/ "1", IconResourceID = 400)]
    [Guid(GuidList.guidSolutionSettingsPkgString)]
    public sealed class SolutionSettingsPackage : Package {
        public SolutionSettingsPackage() {
#if DEBUG
            Trace.TraceInformation("Entering constructor for: {0}", this);
#endif
        }

        private SettingsManager Manager;

        private EnvDTE.DTE DTE;
        private EnvDTE.DTEEvents DTEEvents;
        private EnvDTE.SolutionEvents SolutionEvents;

        protected override void Initialize() {
#if DEBUG
            Trace.TraceInformation("Entering Initialize() of: {0}", this);
#endif
            base.Initialize();

            // Prepare our trace messages. In Debug, all messages go to the log.
            // In Release, only warnings and errors.
            var activityLogListener = new ActivityLogTraceListener(this);
#if !DEBUG
            activityLogListener.Filter = new NoInformationTraceFilter();
#endif
            Trace.Listeners.Add(activityLogListener);

            // Prepare our settings manager
            Manager = new SettingsManager(new DefaultFileSystem(), new DefaultSettingsProvider());

            // Prepare events
            DTE = GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            if (DTE != null) {
                DTEEvents = DTE.Events.DTEEvents;
                SolutionEvents = DTE.Events.SolutionEvents;
                
                DTEEvents.OnBeginShutdown +=
                    new EnvDTE._dispDTEEvents_OnBeginShutdownEventHandler(DTEEvents_OnBeginShutdown);
                SolutionEvents.Opened += 
                    new EnvDTE._dispSolutionEvents_OpenedEventHandler(SolutionEvents_Opened);
                SolutionEvents.QueryCloseSolution +=
                    new EnvDTE._dispSolutionEvents_QueryCloseSolutionEventHandler(SolutionEvents_QueryCloseSolution);
                SolutionEvents.Renamed +=
                    new EnvDTE._dispSolutionEvents_RenamedEventHandler(SolutionEvents_Renamed);
                SolutionEvents.AfterClosing +=
                    new EnvDTE._dispSolutionEvents_AfterClosingEventHandler(SolutionEvents_AfterClosing);
            }
        }

        internal void SolutionEvents_Opened() {
            Manager.SolutionOpened(DTE.Solution);
        }

        internal void SolutionEvents_Renamed(string OldName) {
            Manager.SolutionRenamed(OldName);
        }

        internal void SolutionEvents_QueryCloseSolution(ref bool fCancel) {
            fCancel = !Manager.CanSolutionClose();
        }

        internal void SolutionEvents_AfterClosing() {
            Manager.SolutionClosed();
        }

        internal void DTEEvents_OnBeginShutdown() { }
    }
}
